package cn.shengchao.rule.engine;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import cn.shengchao.rule.base.*;
import cn.shengchao.rule.condition.ICondition;
import cn.shengchao.rule.condition.LogicalOperatorCs;
import org.wildfly.common.annotation.NotNull;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @program: examstarapi
 * @description: 规则引擎
 * @author: Xiong weiqiang
 * @create: 2025-04-07 21:10
 */
public class RuleEngine {
//    private static CopyOnWriteArrayList<IRule> rules=new CopyOnWriteArrayList<>(); // 规则列表
    public static final String RULE_ENGINE_LOCK_KEY="RULE_ENGINE_LOCK_KEY:";
    public static final String RULE_ENGINE_LOAD_KEY="RULE_ENGINE_LOAD_KEY:";
    public static final String RULE_ENGINE_RULE_CONTENT_LIST_KEY="RULE_ENGINE_RULE_CONTENT_LIST_KEY@YSXG";

    public static void cleanAndLoadRules(@NotNull List<IRule> addRules){
        SpringUtil.getBean(RuleManager.class).cleanAndLoadRules(addRules);
    }
    public static void clearRule(IRule r){
        SpringUtil.getBean(RuleManager.class).clearRule(r);
    }
    public static void replaceRule(IRule r){
        SpringUtil.getBean(RuleManager.class).replaceRule(r);
    }

    // 根据输入数据匹配规则并执行动作
    public static List<ConditionGroup> executeRules(Map<String,String> inputData) {
//        List<IRule> copyRules = new ArrayList<>(rules);
        List<IRule> copyRules = SpringUtil.getBean(RuleManager.class).getAllRules();

        if (copyRules == null || copyRules.isEmpty()) {
            copyRules=new ArrayList<>();
        }else {
            copyRules=CollUtil.sort(new ArrayList<>(copyRules), (o1, o2) -> o2.getPriority().compareTo(o1.getPriority()));
        }

        List<ConditionGroup> matchingRules = new ArrayList<>();
        System.out.println("规则数据：" + copyRules.size()+"条"+JSONUtil.toJsonStr(copyRules));
        for (IRule rule : copyRules) {
            // 检查规则是否在生效时间内
            if (!isRuleActive(rule)) {
                System.out.println("规则不在生效期：" + rule.getName());
                continue;
            }
            for (ConditionGroup conditionGroup : rule.getConditionGroups()) {
                System.out.println("当前规则："+rule.getId()+":" + rule.getName()+"，条件组" + JSONUtil.toJsonStr(conditionGroup));
                if (matchConditions(conditionGroup, inputData)) {
                    System.out.println("匹配到规则："+rule.getId()+":" + rule.getName());
                    matchingRules.add(conditionGroup);
                }else{
                    System.out.println("当前规则：" + JSONUtil.toJsonStr(conditionGroup));
                }
            }
        }
        System.out.println("未匹配到规则：" + JSONUtil.toJsonStr(inputData));
        return matchingRules;
    }

    // 检查规则是否在生效时间内
    private static boolean isRuleActive(IRule rule) {
        LocalDateTime now = LocalDateTime.now();
        return now.isAfter(rule.getStartTime()) && now.isBefore(rule.getEndTime());
    }

    // 递归检查条件组是否满足
    private static boolean matchConditions(ConditionGroup conditionGroup, Map<String,String> inputData) {
        List<ICondition> conditions = conditionGroup.getConditions();
        // 检查当前条件组的条件
        List<Boolean> conditionResults = new ArrayList<>();
        for (ICondition condition : conditions) {
            conditionResults.add(matchCondition(condition, inputData));
        }
        // 根据逻辑运算符判断结果
        if (conditionGroup.loadLogicalOperator().equals(LogicalOperatorCs.AND)) {
            return conditionResults.stream().allMatch(result -> result);
        }
        // 根据逻辑运算符判断结果
        if (conditionGroup.loadLogicalOperator().equals(LogicalOperatorCs.OR)) {
            return conditionResults.stream().anyMatch(result -> result);
        }
        return false;
    }

    // 检查单个条件是否满足
    private static boolean matchCondition(ICondition condition, Map<String,String> inputData) {
        return condition == null || condition.isMatch(inputData);
    }

}